package com.googlecode.dgwt.client.dojo.data.base;

import com.googlecode.dgwt.client.dojo.data.listener.AttachListener;
import com.googlecode.dgwt.client.dojo.exception.AttachException;
import com.googlecode.dgwt.client.dojo.util.SharedList;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class StoreListenerList<Item, Listener extends AttachListener<Store<Item>>> extends SharedList<Listener>{

    private StoreListenerList<Item,?> associatedListenerList;
    private Store<Item> store;
    
    public StoreListenerList(Store<Item> store) {
        this.store = store;
    }

    @Override
    protected Store<Item> getParent() {
        return store;
    }
    
    protected void setAssociatedListenerList(StoreListenerList<Item,?> listenerList){        
        assert(listenerList != this);
        
        if (associatedListenerList != null){
            associatedListenerList.associatedListenerList = null;
        }
        
        associatedListenerList = listenerList;
        
        if (associatedListenerList != null){
            associatedListenerList.associatedListenerList = this;
        }
    }
    
    protected boolean canNotifyAttach(Listener listener){
        return associatedListenerList == null || !associatedListenerList.contains(listener);
    }

    protected boolean canNotifyDetach(Listener listener){
        return associatedListenerList == null || !associatedListenerList.contains(listener);
    }
    
    protected void notifyAttach(Listener listener) throws AttachException{
        if (canNotifyAttach(listener)){
            listener.onAttach(getParent());
        }
    }

    protected void notifyDetach(Listener listener){
        if (canNotifyDetach(listener)){
            listener.onDetach(getParent());
        }
    }

    @Override
    protected void onBeforeAdd(int index, Listener listener) throws AttachException {
        notifyAttach(listener);
    }

    @Override
    protected void onAfterRemove(int index, Listener listener) {
        notifyDetach(listener);
    }

    @Override
    protected void onBeforeReplace(int index, Listener oldListener, Listener newListener) throws AttachException {
        onBeforeAdd(index, newListener);
    }

    @Override
    protected void onAfterReplace(int index, Listener oldListener, Listener newListener) {
        onAfterRemove(index, oldListener);
    }

}